"""
代码块提取工具

这个模块提供了从文本中提取标准 SEARCH/REPLACE block 的功能。

标准格式示例:
    ##File: path/to/file.py
    <<<<<<< SEARCH
    old_content
    =======
    new_content
    >>>>>>> REPLACE

提取结果示例:
    返回包含完整 block 的列表，每个元素类似：
    ##File: path/to/file.py
    <<<<<<< SEARCH
    old_content
    =======
    new_content
    >>>>>>> REPLACE
"""
import re
from typing import List,Tuple
import os

class BlockExtractor:
    """
    代码块提取器
    
    用于从文本中提取标准格式的 SEARCH/REPLACE block。
    支持提取多个修改块。
    """
    
    @staticmethod
    def extract_blocks(content: str) -> List[str]:
        """
        从文本中提取所有标准格式的 SEARCH/REPLACE block
        
        Args:
            content: 包含一个或多个修改块的文本
            
        Returns:
            List[str]: 包含完整 SEARCH/REPLACE block 的列表
            
        示例输入:
            Some text...
            ##File: example.py
            <<<<<<< SEARCH
            old code
            =======
            new code
            >>>>>>> REPLACE
            Other text...
            
        示例输出:
            ['##File: example.py\\n<<<<<<< SEARCH\\nold code\\n=======\\nnew code\\n>>>>>>> REPLACE']
        """
        blocks = []
        
        # 使用正则表达式匹配完整的块
        pattern = (
             r'##File:\s*([^\n]+)\n'          # 匹配文件头
            r'<<<<<<< SEARCH\n'              # 匹配 SEARCH 标记
            r'([\s\S]*?)\n?=======\n'        # 匹配搜索内容直到 =======
            r'([\s\S]*?)\n>>>>>>> REPLACE'   # 匹配替换内容直到 REPLACE
        )
        
        matches = re.finditer(pattern, content, re.DOTALL)
        
        for match in matches:
            file_path = match.group(1).strip()
            search_content = match.group(2).rstrip()
            replace_content = match.group(3).rstrip()
            
            # 构建完整的块
            block = (
                f"##File: {file_path}\n"
                f"<<<<<<< SEARCH\n"
                f"{search_content}\n"
                f"=======\n"
                f"{replace_content}\n"
                f">>>>>>> REPLACE"
            )
            blocks.append(block)
        
        return blocks 

    @staticmethod
    def write_blocks_to_patch(content: str) -> None:
        """
        将提取的 SEARCH/REPLACE blocks 写入到工作目录下的 output.patch 文件
        
        这个方法会：
        1. 从输入内容中提取所有标准格式的 blocks
        2. 将这些 blocks 写入到工作目录下的 output.patch 文件
        3. 如果文件已存在，会先清空内容
        
        Args:
            content: 包含一个或多个修改块的文本
            
        Raises:
            ValueError: 当工作目录未设置时
            IOError: 当文件写入失败时
        """
        from src.config import GlobalConfig
        
        # 获取工作目录
        work_dir = GlobalConfig.get_work_dir()
        if not work_dir:
            raise ValueError("工作目录未设置")
            
        # 提取所有 blocks
        blocks = BlockExtractor.extract_blocks(content)
        
        # 构建输出文件路径
        patch_file = os.path.join(work_dir, 'output_diff.patch')
        
        try:
            # 写入文件（'w' 模式会自动清空文件内容）
            with open(patch_file, 'w', encoding='utf-8') as f:
                if blocks:
                    # 用换行符连接所有 blocks
                    f.write('\n\n'.join(blocks))
        except Exception as e:
            raise IOError(f"写入补丁文件失败: {str(e)}") 

    @staticmethod
    def join_blocks(content: str) -> str:
        """
        从输入字符串中提取并拼接所有 SEARCH/REPLACE blocks
        
        Args:
            content: 包含一个或多个修改块的文本
            
        Returns:
            str: 拼接后的标准格式字符串
            
        示例输入:
            Some text...
            ##File: example1.py
            <<<<<<< SEARCH
            old1
            =======
            new1
            >>>>>>> REPLACE
            
            Some other text...
            ##File: example2.py
            <<<<<<< SEARCH
            old2
            =======
            new2
            >>>>>>> REPLACE
            
        示例输出:
            ##File: example1.py
            <<<<<<< SEARCH
            old1
            =======
            new1
            >>>>>>> REPLACE
            
            ##File: example2.py
            <<<<<<< SEARCH
            old2
            =======
            new2
            >>>>>>> REPLACE
        """
        # 先提取所有的 blocks
        blocks = BlockExtractor.extract_blocks(content)
        
        if not blocks:
            return ""
            
        # 用两个换行符连接所有 blocks，确保每个 block 之间有空行
        return "\n\n".join(blocks) 
    

    @staticmethod
    def parse_search_replace_blocks(content: str) -> List[Tuple[str, str, str]]:
        """
        解析标准格式的 SEARCH/REPLACE blocks
        
        Args:
            content: 包含一个或多个标准格式 block 的字符串
            
        Returns:
            List[Tuple[str, str, str]]: 包含 (文件路径, 搜索内容, 替换内容) 的列表
        """
        blocks = []
        
        # 使用正则表达式匹配完整的块
        pattern = r'##File:\s*(.*?)\s*<<<<<<< SEARCH\s*([\s\S]*?)\s*=======\s*([\s\S]*?)\s*>>>>>>> REPLACE'
        # pattern = r'##File:\s*(.*?)\n<<<<<<< SEARCH\n(.*?)\n=======\n(.*?)\n>>>>>>> REPLACE'
        content = content.replace('\r\n','\n')
        # 使用 re.DOTALL 标志来让 . 匹配换行符
        matches = re.finditer(pattern, content, re.DOTALL)
        
        for match in matches:
            file_path = match.group(1).strip()
            search_content = match.group(2).rstrip()
            replace_content = match.group(3).rstrip()
            
            # 只有当文件路径不为空时才添加
            if file_path:
                blocks.append((file_path, search_content, replace_content))
        
        return blocks
    
    @staticmethod
    def extract_commit_message(content: str) -> str:
        """
        从文本中提取commit message
        
        Args:
            content: 包含commit message的文本，格式为 [###]commit message[###]
            
        Returns:
            str: 提取到的commit message，如果没有找到则返回空字符串
        """
        pattern = r'\[###\]([\s\S]*?)\[###\]'
        match = re.search(pattern, content)
        
        if match:
            return match.group(1).strip()
        return ""
    
    